#include "syscall.h"
#include "print.c"

#define TICKS	50

int lock;
int otherLock;
int condition;
int otherCondition;

int main()
{
	int i;
	int printMsg[5];

	printString("--> System Test 5 Program 0 <--\n");

	lock = CreateLock();
	condition = CreateCondition();

	printMsg[0] = lock;
	printMsg[1] = condition;
	printf("[Program 0] Lock %d created, Condition %d created.\n", printMsg);

	if (lock == 0) {
		otherLock = 1;
	}
	else {
		otherLock = 0;
	}

	if (condition == 0) {
		otherCondition = 1;
	}
	else {
		otherCondition = 0;
	}

	for (i = 0; i < TICKS; i++) {
		Yield();
	}

	printMsg[0] = otherLock;
	printf("[Program 0] Trying to acquire Lock %d\n", printMsg);
	Acquire(otherLock);
	printMsg[0] = lock;
	printf("[Program 0] Trying to acquire Lock %d\n", printMsg);
	Acquire(lock);

	printMsg[0] = otherLock;
	printf("[Program 0] Trying to release Lock %d\n", printMsg);
	Release(otherLock);
	printMsg[0] = lock;
	printf("[Program 0] Trying to release Lock %d\n", printMsg);
	Release(lock);

	printMsg[0] = otherLock;
	printf("[Program 0] Trying to destroy Lock %d\n", printMsg);
	DestroyLock(otherLock);
	printMsg[0] = lock;
	printf("[Program 0] Trying to destroy Lock %d\n", printMsg);
	DestroyLock(lock);

	printMsg[0] = otherCondition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to signal condition %d with Lock %d\n", printMsg);
	Signal(otherCondition, otherLock);
	printMsg[0] = condition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to signal condition %d with Lock %d\n", printMsg);
	Signal(condition, otherLock);
	printMsg[0] = otherCondition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to signal condition %d with Lock %d\n", printMsg);
	Signal(otherCondition, lock);
	printMsg[0] = condition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to signal condition %d with Lock %d\n", printMsg);
	Signal(condition, lock);

	printMsg[0] = otherCondition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to broadcast condition %d with Lock %d\n", printMsg);
	Broadcast(otherCondition, otherLock);
	printMsg[0] = condition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to broadcast condition %d with Lock %d\n", printMsg);
	Broadcast(condition, otherLock);
	printMsg[0] = otherCondition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to broadcast condition %d with Lock %d\n", printMsg);
	Broadcast(otherCondition, lock);
	printMsg[0] = condition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to broadcast condition %d with Lock %d\n", printMsg);
	Broadcast(condition, lock);

	printMsg[0] = otherCondition;
	printf("[Program 0] Trying to destroy Condition %d\n", printMsg);
	DestroyCondition(otherCondition);
	printMsg[0] = condition;
	printf("[Program 0] Trying to destroy Condition %d\n", printMsg);
	DestroyCondition(lock);

	/* Recreate the lock and condition variable we have destroyed previously */
	lock = CreateLock();
	condition = CreateCondition();

	printMsg[0] = lock;
	printMsg[1] = condition;
	printf("[Program 0] Lock %d created, Condition %d created.\n", printMsg);

	if (lock == 0) {
		otherLock = 1;
	}
	else {
		otherLock = 0;
	}

	if (condition == 0) {
		otherCondition = 1;
	}
	else {
		otherCondition = 0;
	}

	printMsg[0] = lock;
	printf("[Program 0] Trying to acquire Lock %d\n", printMsg);
	Acquire(lock);

	printMsg[0] = otherCondition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to wait condition %d with Lock %d\n", printMsg);
	Wait(otherCondition, otherLock);
	printMsg[0] = condition;
	printMsg[1] = otherLock;
	printf("[Program 0] Trying to wait condition %d with Lock %d\n", printMsg);
	Wait(condition, otherLock);
	printMsg[0] = otherCondition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to wait condition %d with Lock %d\n", printMsg);
	Wait(otherCondition, lock);
	printMsg[0] = condition;
	printMsg[1] = lock;
	printf("[Program 0] Trying to wait condition %d with Lock %d ..... [Program 0 is blocked here forever]\n", printMsg);
	Wait(condition, lock);

	Exit(0);
}
